481f6e3ac749efdf72c23679ba595f3de0ad2924,src/freenet/clients/http/HTTPRequestImpl.java,HTTPRequestImpl,parseMultiPartData,#,377

Before Change


		if(data == null) return;
		String ctype = (String) this.headers.get("content-type");
		if (ctype == null) return;
		if(Logger.shouldLog(Logger.MINOR, this))
			Logger.minor(this, "Uploaded content-type: "+ctype);
		String[] ctypeparts = ctype.split(";");
		if(ctypeparts[0].equalsIgnoreCase("application/x-www-form-urlencoded")) {

After Change


	 * params, whereas if it is multipart/form-data it will be separated into buckets.
	 */
	private void parseMultiPartData() throws IOException {
		boolean logMINOR = Logger.shouldLog(Logger.MINOR, this);
		if(data == null) return;
		String ctype = (String) this.headers.get("content-type");
		if (ctype == null) return;
		if(logMINOR)
			Logger.minor(this, "Uploaded content-type: "+ctype);
		String[] ctypeparts = ctype.split(";");
		if(ctypeparts[0].equalsIgnoreCase("application/x-www-form-urlencoded")) {
			// Completely different encoding, but easy to handle
			if(data.size() > 1024*1024)
				throw new IOException("Too big");
			byte[] buf = BucketTools.toByteArray(data);
			String s = new String(buf, "us-ascii");
			parseRequestParameters(s, true, true);
		}
		if (!ctypeparts[0].trim().equalsIgnoreCase("multipart/form-data") || (ctypeparts.length < 2)) {
			return;
		}
		
		String boundary = null;
		for (int i = 0; i < ctypeparts.length; i++) {
			String[] subparts = ctypeparts[i].split("=");
			if ((subparts.length == 2) && subparts[0].trim().equalsIgnoreCase("boundary")) {
				boundary = subparts[1];
			}
		}
		
		if ((boundary == null) || (boundary.length() == 0)) return;
		if (boundary.charAt(0) == '"') boundary = boundary.substring(1);
		if (boundary.charAt(boundary.length() - 1) == '"')
			boundary = boundary.substring(0, boundary.length() - 1);
		
		boundary = "--"+boundary;
		
		if(logMINOR)
			Logger.minor(this, "Boundary is: "+boundary);
		
		InputStream is = this.data.getInputStream();
		BufferedInputStream bis = new BufferedInputStream(is, 32768);
		LineReadingInputStream lis = new LineReadingInputStream(bis);
		
		String line;
		line = lis.readLine(100, 100, false); // really it's US-ASCII, but ISO-8859-1 is close enough.
		while ((bis.available() > 0) && !line.equals(boundary)) {
			line = lis.readLine(100, 100, false);
		}
		
		boundary  = "\r\n"+boundary;
		
		Bucket filedata = null;
		String name = null;
		String filename = null;
		String contentType = null;
		
		while(bis.available() > 0) {
			name = null;
			filename = null;
			contentType = null;
			// chomp headers
			while( (line = lis.readLine(200, 200, true)) /* should be UTF-8 as we told the browser to send UTF-8 */ != null) {
				if (line.length() == 0) break;
				
				String[] lineparts = line.split(":");
				if (lineparts == null || lineparts.length == 0) continue;
				String hdrname = lineparts[0].trim();
				
				if (hdrname.equalsIgnoreCase("Content-Disposition")) {
					if (lineparts.length < 2) continue;
					String[] valueparts = lineparts[1].split(";");
					
					for (int i = 0; i < valueparts.length; i++) {
						String[] subparts = valueparts[i].split("=");
						if (subparts.length != 2) {
							continue;
						}
						String fieldname = subparts[0].trim();
						String value = subparts[1].trim();
						if (value.startsWith("\"") && value.endsWith("\"")) {
							value = value.substring(1, value.length() - 1);
						}
						if (fieldname.equalsIgnoreCase("name")) {
							name = value;
						} else if (fieldname.equalsIgnoreCase("filename")) {
							filename = value;
						}
					}
				} else if (hdrname.equalsIgnoreCase("Content-Type")) {
					contentType = lineparts[1].trim();
					if(Logger.shouldLog(Logger.MINOR, this)) Logger.minor(this, "Parsed type: "+contentType);
				} else {
					// Do nothing, irrelevant header
				}
			}
			
			if (name == null) continue;
			
			// we should be at the data now. Start reading it in, checking for the
			// boundary string
			
			// we can only give an upper bound for the size of the bucket
			filedata = this.bucketfactory.makeBucket(bis.available());
			OutputStream bucketos = filedata.getOutputStream();
			OutputStream bbos = new BufferedOutputStream(bucketos, 32768);
			// buffer characters that match the boundary so far
			// FIXME use whatever charset was used
			byte[] bbound = boundary.getBytes("UTF-8"); // ISO-8859-1? boundary should be in US-ASCII
			int offset = 0;
			while ((bis.available() > 0) && (offset < bbound.length)) {
				byte b = (byte)bis.read();
				
				if (b == bbound[offset]) {
					offset++;
					if(logMINOR)
						Logger.minor(this, "Matched "+offset+" of "+bbound.length+" : "+b);
				} else if ((b != bbound[offset]) && (offset > 0)) {
					// offset bytes matched, but no more
					// write the bytes that matched, then the non-matching byte
					bbos.write(bbound, 0, offset);
					bbos.write((int) b & 0xff);
					if(logMINOR)
						Logger.minor(this, "Partial match: "+offset+" of "+bbound.length+" matched, no more because b = "+b);
					offset = 0;
				} else {
					bbos.write((int) b & 0xff);